#!/bin/bash
# Copyright (c) 2011, bkil.hu
# This program is free software and can be distributed under the terms of
# the GNU General Public License v2,
# see COPYING for detailed licensing terms.

# TODO: better compatibility with autosuspend
# cron would need admin or group privileges...
# created on 2010-12-30

# /etc/sudoers:
# %rtc ALL = NOPASSWD: /usr/sbin/rtcwake

testmain(){
 RECORD=rectest
 ISCURRENT=istestcurrent
 DELAY="sleeptest "
 for a in tv2 duna rtl m1 m2 film+ ;do
  echo "$a : " `getnamedfq $a`
 done
 cat <<EOF |
12 34 m1
12 35 m2
12 36
EOF
 loop
}

iscurrent_first4(){
 I=`expr 0$I + 1`
 [ $I -le 2 ]
}

istestcurrent(){
 true
}

sleeptest(){
 echo sleep "$@" >&2
 sleep 1
}

rectest(){
 echo record "$@" >&2
}

main(){
 RECORD=$HOME/bin/rec.sh
 ISCURRENT=iscurrent
# ISCURRENT=iscurrent_first4
 DELAY=sleep
 cat "$@" |
 loop
}

iscurrent(){
 [ `date +%H` -eq $H ] &&
 [ `date +%M` -eq $M ]
}

loop(){
 SLEEPTRESH=`expr 60 \* 60` #suspend threshold in seconds
 WAKELATENCY=120 #seconds before alarm to wake up
 TRAPS="1 2 3 15"
 ENC=""
 PID=$$
 ATOM=20
 cd $HOME/Videos ||err "missing video folder"
 checkcard_self
 set_destructor volmax
 IS_RECORD=""
 while read H M C;do
  echo "$H $M $C"
  if [ -n "$IS_RECORD" ] ;then
   waituntil $H $M
  else
   sleepuntil $H $M
  fi
  killenc
  [ -n "$C" ] && recordch $C
 done
 killenc
 suspend_if_unused
 true
}

sleepuntil(){
 local H=$1
 local M=$2

 local ABSTIME=`date -d "$H:$M" "+%s"`
 local ABSNOW=`date "+%s"`
 [ $ABSTIME -le $ABSNOW ] && 
  ABSTIME=`expr $ABSTIME + 24 \* 60 \* 60`
 ABSTIME=`expr $ABSTIME - $WAKELATENCY`
# DST="" #daylight saving
# if [ -n "$DST" ] ;then
  sudo rtcwake -v -m no -l -t $ABSTIME
# else
#  sudo rtcwake -v -m no -u -t $ABSTIME
# fi

 TOSLEEP=`expr $ABSTIME - $ABSNOW`
 if [ $TOSLEEP -gt $SLEEPTRESH ] ;then
  suspend_if_unused
 fi

 #TODO: maybe try to sleep later on
 waituntil $H $M
}

suspend_if_unused(){
 if ! \
  { xscreensaver-command -time 2>/dev/null || echo "non-blanked"; } |
  grep -q "non-blanked"
 then
  printf "DEBUG: suspend: %s\n" "`date`"
  $HOME/bin/suspend.sh
  printf "DEBUG: wake-up: %s\n" "`date`"
 fi
}

waituntil(){
 local H=$1
 local M=$2
 while ! $ISCURRENT $H $M;do
  $DELAY $ATOM # TODO: sleep more if possible
 done
}

volmin(){
 amixer sset 'CD' 10% # TV line playback volume
}

volmax(){
 amixer sset 'CD' 100% # TV line playback volume
}

checkcard_self(){
 # TODO: perhaps we could refresh the timetable in this case
 isrunning `basename $0` &&
  err "$0 running"
}

checkcard_rec(){
 # TODO: maybe we should kill these instead...
 for a in `pidof mencoder`;do
  grep -qz '\<tv://' /proc/$a/cmdline &&
   err "mencoder running"
 done

 # DEBUG
 killall tvtime
 sleep 2

 # TODO: kill it, remember the fact, view the recording, reopen afterwards
 pidof tvtime &&
  err "tvtime running"

 true
}

isrunning(){
 local PG="$1"
 local OMYPIDS="`
   getdeepchildren $PID |
   while read a;do
    printf '%s' ' -o ' $a
   done`"
 pidof -x $OMYPIDS $PG >/dev/null
}

getdeepchildren(){
 for a in "$@"; do
  echo "$a"
 done
 ps --no-heading -o pid --ppid "$@" ||err ps
}

err(){
 echo "error: $@" >&2
 exit 1
}

set_destructor(){
 for a in $TRAPS;do
  trap "$1 ; \
        trap - EXIT $TRAPS ; \
        kill -$a $PID" $a
 done
 trap "$1 ; \
       trap - EXIT $TRAPS" EXIT 

}

killenc() {
 if [ -n "$ENC" ];then
  kill $ENC
  local RES=$?
  IS_RECORD=""
  set_destructor volmax
  wait $ENC
  volmax
  echo "debug: mencoder kill & wait complete" >&2
  ENC=""
 fi
 return $RES
}

recordch(){
 local C=$1
 local F=`getnamedfq $C`
 if [ -n "$F" ];then
  checkcard_rec
  volmin 
  $RECORD $F & ENC=$!
#  sleep 7
#  nice -n1 mplayer -framedrop -quiet -fs -osdlevel 3 -vf pp=ac `ls $HOME/Videos|tail -n1` & MPL=$!
  IS_RECORD="1"
  set_destructor "volmax ;\
        kill $ENC $MPL ; \
        wait $ENC"
  sleep 10 # if a kill would be triggered right away
 else
  echo "error: ignored unknown channel '${C}'" >&2
 fi
}

getnamedfq(){
 local N="$1"
 grep -i "<station [^>]*\<name=\"[^\"]*${N}[^\"]*\""  $HOME/.tvtime/stationlist.xml |
 grep ' active="1"' |
 head -n 1 |
 sed 's~^.*\<channel="\([1-9][0-9]*\.[0-9][0-9]*\)MHz".*$~\1~'
}

main "$@"
